/****************************************************************************
Copyright (c) 2015-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
 
http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
package org.cocos2dx.cpp;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Bundle;
import org.cocos2dx.lib.Cocos2dxActivity;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.KeyEvent;
import android.view.WindowManager;
import android.widget.Toast;
import android.support.v4.app.ActivityCompat;

import com.ndmooc.ktwelve.mvp.home.model.bean.GoodCopyData;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static android.bluetooth.BluetoothDevice.TRANSPORT_LE;
import com.tstudy.blepenlib.BlePenStreamManager;
import com.tstudy.blepenlib.callback.BleGattCallback;
import com.tstudy.blepenlib.callback.BlePenStreamCallback;
import com.tstudy.blepenlib.callback.BleScanCallback;
import com.tstudy.blepenlib.data.BleDevice;
import com.tstudy.blepenlib.data.CoordinateInfo;
import com.tstudy.blepenlib.exception.BleException;

import static com.tstudy.blepenlib.constant.Constant.PEN_COODINAT_MESSAGE;
import static com.tstudy.blepenlib.constant.Constant.PEN_DOWN_MESSAGE;
import static com.tstudy.blepenlib.constant.Constant.PEN_UP_MESSAGE;

import com.zxybpen.sdk.sdk.ZXYBSdk;


public class AppActivity extends Cocos2dxActivity {
    private static final int REQUEST_ENABLE_BT = 100;

    /*蓝牙连接*/
    private BluetoothAdapter bluetoothAdapter;
    private boolean mScanning;
    //private Handler handler;
    private BluetoothLeScanner mBluetoothLeScanner;
    // Stops scanning after 10 seconds.
    private static final long SCAN_PERIOD = 10000;

    // Initializes Bluetooth adapter.
    BluetoothManager bluetoothManager;
    private static AppActivity selfMe = null;
    private HashMap<String, BluetoothDevice> scanBLEList = new HashMap<String, BluetoothDevice>();
    private HashMap<String, BleDevice> scanHSDBLEList = new HashMap<String, BleDevice>();

    BluetoothGatt bluetoothGatt;
    private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    private UUID read_UUID_chara = null;
    private UUID read_UUID_service = null;
    private UUID write_UUID_chara = null;
    private UUID write_UUID_service = null;
    private UUID notify_UUID_service = null;
    private UUID notify_UUID_chara = null;
    private UUID indicate_UUID_chara = null;
    private UUID indicate_UUID_service = null;

    private BleDevice connnectedDevice = null;

    private static final int ZXYB_DATA = 2;//画笔的坐标值
    private static final int ZXYB_KEY_INDEX = 3;//慧板左侧工具栏按键值
    private static final int ZXYB_BLE_STATUS = 4; //蓝牙状态
    private static final int ZXYB_PEN_TYPE = 5;//笔的状态
    private Messenger btB5clientMessenger, btB5serverMessenger;
    public static final String ZXYB_MOUSE_STATUS_ACTION = "zxyb.intent.action.MOUSE";

    private boolean isBtB5Connect = false;
    private int btB5Type;// 0 :画笔  1:鼠标  默认下是鼠标
    static private boolean isFromTongMeng;//是否童蒙来的
    static private long lastTongMengTimestamp = 0;//
    static private GoodCopyData oneGCD;
    ExecutorService writeReportThreadExecutor = Executors.newSingleThreadExecutor();

    BluetoothGattCallback mBluetoothGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);

            Log.d("bttt-java", "onConnectionStateChange");
            switch (newState) {//对蓝牙反馈的状态进行判断
                case BluetoothProfile.STATE_CONNECTED://已链接
                    try {
                        Thread.sleep(600);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    gatt.discoverServices();
                    ScaningNotify(1,"已连接蓝牙");
                    break;
                case BluetoothProfile.STATE_DISCONNECTED://已断开
                    Log.d("bttt", "STATE_DISCONNECTED");
                    ScaningNotify(-1,"已断开连接");
                    BLEDisconnect();
                    break;
            }
            //连接状态改变回调
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            Log.i("bttt","onServicesDiscovered");
            ScaningNotify(2,"发现蓝牙服务");

            super.onServicesDiscovered(gatt, status);
            if(status == BluetoothGatt.GATT_SUCCESS) {

                //获取初始化服务和特征值 getIncludedServices
                List<BluetoothGattService> bluetoothGattServices = gatt.getServices();

                for (BluetoothGattService bluetoothGattService:bluetoothGattServices){
                    if(bluetoothGattService.getType() != BluetoothGattService.SERVICE_TYPE_PRIMARY){
                        //continue;
                    }

                    List<BluetoothGattCharacteristic> characteristics=bluetoothGattService.getCharacteristics();
                    for (BluetoothGattCharacteristic characteristic:characteristics){
                        int charaProp = characteristic.getProperties();
                        if ((charaProp & BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
                            read_UUID_chara=characteristic.getUuid();
                            read_UUID_service=bluetoothGattService.getUuid();
                            Log.d("bttt","read_chara="+read_UUID_chara+"----read_service="+read_UUID_service);
                            ScaningNotify(3,"读服务地址:"+read_UUID_service);
                        }
                        if ((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
                            write_UUID_chara=characteristic.getUuid();
                            write_UUID_service=bluetoothGattService.getUuid();
                            Log.d("bttt","write_chara="+write_UUID_chara+"----write_service="+write_UUID_service);
                            ScaningNotify(3,"写服务地址:"+write_UUID_service);
                        }
                        if ((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) > 0) {
                            //write_UUID_chara=characteristic.getUuid();
                            //write_UUID_service=bluetoothGattService.getUuid();
                            //Log.d("bttt","write_chara="+write_UUID_chara+"----write_service="+write_UUID_service);

                        }
                        if ((charaProp & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                            notify_UUID_chara=characteristic.getUuid();
                            notify_UUID_service=bluetoothGattService.getUuid();
                            Log.d("bttt","notify_chara="+notify_UUID_chara+"----notify_service="+notify_UUID_service);
                            ScaningNotify(3,"通知服务地址:"+notify_UUID_service);
                        }
                        if ((charaProp & BluetoothGattCharacteristic.PROPERTY_INDICATE) > 0) {
                            indicate_UUID_chara=characteristic.getUuid();
                            indicate_UUID_service=bluetoothGattService.getUuid();
                            Log.d("bttt","indicate_chara="+indicate_UUID_chara+"----indicate_service="+indicate_UUID_service);
                            ScaningNotify(3,"探测服务地址:"+indicate_UUID_service);
                        }
                    }
                }

                //订阅通知
                BluetoothGattCharacteristic oneCharact = bluetoothGatt.getService(notify_UUID_service).getCharacteristic(notify_UUID_chara);

                //Log.d("bttt", "bluetoothGatt.getService(notify_UUID_service).getCharacteristic())");
                bluetoothGatt.setCharacteristicNotification(oneCharact,true);

                List<BluetoothGattDescriptor> oneDescList = oneCharact.getDescriptors();
                if(oneDescList.size()>0){
                    boolean rxet = oneDescList.get(0).setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                    //Log.d("bttt", String.valueOf(rxet));
                }

                //订阅通知
                BluetoothGattCharacteristic oneCharactW = bluetoothGatt.getService(notify_UUID_service).getCharacteristic(write_UUID_chara);

                //Log.d("bttt", "bluetoothGatt.getService(notify_UUID_service).getCharacteristic())");
                bluetoothGatt.setCharacteristicNotification(oneCharact,true);

                List<BluetoothGattDescriptor> oneDescListW = oneCharact.getDescriptors();
                if(oneDescList.size()>0){
                    boolean rxet = oneDescList.get(0).setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                    ScaningNotify(3,"打开通知功能");
                    //Log.d("bttt", String.valueOf(rxet));
                }

                if(oneDescList.size()>0){
                    bluetoothGatt.writeDescriptor(oneDescList.get(0));
                    ScaningNotify(3,"写入描述字");
                    BLEConnectSuccess(1);
                }
            }else{
                Log.d("bttt","OnCallback2 fail");
            }

            //连接回调，status为0时连接成功
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicRead(gatt, characteristic, status);

            Log.d("bttt","onCharacteristicRead");
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            Log.d("bttt","onCharacteristicWrite");

            super.onCharacteristicWrite(gatt, characteristic, status);
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            final byte[] data=characteristic.getValue();
            if(data.length > 0) {
                //Log.d("bttt", "onCharacteristicChanged got" + String.valueOf(data.length));
                BLEReciveData(data);
            }
        }

        @Override
        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            Log.d("bttt","OnCallback6");

            super.onDescriptorRead(gatt, descriptor, status);
        }

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorWrite(gatt, descriptor, status);

            Log.d("bttt","onDescriptorWrite");
            if(status == BluetoothGatt.GATT_SUCCESS){
            }
        }

        @Override
        public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
            Log.d("bttt","OnCallback8");

            super.onReliableWriteCompleted(gatt, status);
        }

        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
            Log.d("bttt","OnCallback9");

            super.onReadRemoteRssi(gatt, rssi, status);
        }

        @Override
        public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
            Log.d("bttt","OnCallback10");

            super.onMtuChanged(gatt, mtu, status);
        }
    };

    public int lastDrawAct ;
    public float lastDrawX;
    public float lastDrawY;

    //连接回调
    BleGattCallback bleGattCallback = new BleGattCallback() {

        @Override
        public void onStartConnect() {
            /*ScaningNotify(2,"发现蓝牙服务");*/
        }

        @Override
        public void onConnectFail(BleDevice bleDevice, BleException exception) {
            if(connnectedDevice != null) {


                new Timer().schedule(new TimerTask() {
                    @Override
                    public void run() {
                        connectBle();
                    }
                }, 1000);

                ScaningNotify(-1,"断开重连");
            }

            ScaningNotify(-1,"连接错误:"+exception.getDescription());
        }

        @Override
        public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
            //BlePenStreamManager.getInstance().clearMemoryCache();
            if (BlePenStreamManager.getInstance().isConnected(bleDevice)) {
                //开启笔输出流
                BlePenStreamManager.getInstance().openPenStream(bleDevice, mBlePenStreamCallback);
                ScaningNotify(1,"已连接蓝牙");
                BLEConnectSuccess(2);
            }else {
                ScaningNotify(-1,"没连上");
            }
        }

        @Override
        public void onDisConnected(boolean isActiveDisConnected, BleDevice bleDevice, BluetoothGatt gatt, int status) {
            BLEDisconnect();

            if(!isActiveDisConnected){
                ScaningNotify(-1,"断开重连");
                new Timer().schedule(new TimerTask() {
                    @Override
                    public void run() {
                        connectBle();
                    }
                }, 1000);
            }else{
                ScaningNotify(-1,"已断开连接");
                connnectedDevice = null;
            }
        }
    };

    BlePenStreamCallback mBlePenStreamCallback = new BlePenStreamCallback() {
        @Override
        public void onOpenPenStreamStatus(boolean openSuccess, String message) {
            if (openSuccess) {
                Toast.makeText(AppActivity.this,"点阵笔打开成功",Toast.LENGTH_SHORT).show();
                BlePenStreamManager.getInstance().setStandMode();
                //BlePenStreamManager.getInstance().setHoverMode();

            } else {
                Toast.makeText(AppActivity.this,"点阵笔打开失败"+message,Toast.LENGTH_LONG).show();
            }
        }

        @Override
        public void onRemainBatteryAndMemory(final int batteryPercent, final int memoryPercent, final int byteNum) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if(batteryPercent < 10) {
                        Toast.makeText(AppActivity.this, "点阵笔电量低(" + String.valueOf(batteryPercent) + "%)", Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }


        @Override
        public void onCoordDraw(final CoordinateInfo coordinateInfo) {
            /**
             * 输出离线数据坐标信息
             * @param state down/move/up
             * @param pageAddress 点阵地址
             * @param nX 坐标X
             * @param nY 坐标Y
             * @param nForce 压力值
             * @param strokeNum 笔画数
             * @param time 时间戳
             * @param offLineDataAllSize 总离线字节数
             * @param offLineDateCurrentSize 已上传字节数
             */
            if(coordinateInfo.pageAddress == null ||
               coordinateInfo.isOFFLine
            )  return;

/*
            float pw = 5600;
            float ph = 7920;

 */
            float cx = (float)coordinateInfo.coordX/5600.0f;
            float cy = (float)coordinateInfo.coordY/7920.0f;
            int penState = -1;
            switch (coordinateInfo.state) {
                case PEN_DOWN_MESSAGE:
                    //writeString = "down";
                    penState = 1;
                    break;
                case PEN_COODINAT_MESSAGE:
                    if(lastDrawAct == PEN_DOWN_MESSAGE){
                        penState = 1;
                    }else {
                        penState = 2;
                    }

                    Log.d("bttt-java", "\t onCoordDraw= state:"+String.valueOf(coordinateInfo.state)
                            +",pageAddress:"+String.valueOf(coordinateInfo.pageAddress)
                            +"   Vec2("+String.valueOf(cx)
                            +","+String.valueOf(cy)
                            +")  coordForce:"+String.valueOf(coordinateInfo.coordForce)
                            +",strokeNum:"+String.valueOf(coordinateInfo.strokeNum)
                            +",timeLong:"+String.valueOf(coordinateInfo.timeLong)
                            +",isOFFLine:"+String.valueOf(coordinateInfo.isOFFLine)
                    );
                    break;
                case PEN_UP_MESSAGE:
                    //writeString = " up ";

                    cx = lastDrawX;
                    cy = lastDrawY;

                    penState = 3;
                    break;
                default:
                    penState = 4;
                    //writeString = " up ";
            }

            lastDrawAct = coordinateInfo.state;
            lastDrawX = cx;
            lastDrawY = cy;

            if(cx == 0 ||
               cy == 0
            ){
                return;
            }

            HsdBLEReciveData(penState,
                      cx,
                      cy,
                    (float)coordinateInfo.coordForce/1024.0f ,
                    coordinateInfo.strokeNum,
                    coordinateInfo.pageAddress
            );
        }

        @Override
        public void onWarnActiveReport(final int statusNum) {
            //0x05  电池电量低警告  0x08 存储空间警告
            switch (statusNum) {
                case 0x05:
                    Toast.makeText(AppActivity.this, "点阵笔电量低", Toast.LENGTH_LONG).show();
                    break;
            }
        }

        @Override
        public void onVersionAndserialNumber(String hardVersion, final String softVersion, String serialNumber) {

        }


        @Override
        public void onCurrentTime(long penTime) {

        }
    };

    void connectBle()    {
        if(connnectedDevice != null) {
            //BlePenStreamManager.getInstance().disconnect(connnectedDevice);

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.d("bttt-java", "BlePenStreamManager.getInstance().connect(connnectedDevice.getMac(), bleGattCallback);");
                    BlePenStreamManager.getInstance().connect(connnectedDevice.getMac(), bleGattCallback);
                }
            });
        }
    }

    public static String getGoodCopyDataToken()
    {
        String token = "fakeToken";
        if(isFromTongMeng){
            token = oneGCD.getToken();
        }

        return token;
    }
    public static boolean isFromTongMeng(){
        //return true;
        return isFromTongMeng;
    }

    public static AppActivity getMe(){
        if(selfMe == null){
            Log.d("bttt-java", "selfMe == NULL");
        }
        return selfMe;
    }

    @Override
    public boolean onKeyDown(final int pKeyCode, final KeyEvent pKeyEvent) {
        super.onKeyDown(pKeyCode,pKeyEvent);

        //NotifyCommon(cmd);
        //Toast.makeText(AppActivity.this,pKeyEvent.toString(),Toast.LENGTH_LONG).show();

        Keypress2Cpp(pKeyEvent.getScanCode());

        return true;
    }

    public static native void StartBluetoothScan();
    public static native void StopBluetoothScan();
    public static native void ScanCallback(String deviceName,String deviceAddress,int rssi,int deviceVendor);
    public static native void ScaningNotify(int step, String msg);
    public static native void NotifyCommon(String msg);
    public static native void BLEReciveData(byte[] data);
    public static native void HsdBLEReciveData(int penState,float coordX,float coordY,float coordForce,int strokeNum,String pageAddr);
    public static native void BtB5ReciveData(int penState,float coordX,float coordY,float pressure);
    public static native void BleCppInit();
    public static native void Keypress2Cpp(int keyCode);
    public static native void BLEConnectSuccess(int deviceType);
    public static native void BLEDisconnect();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        selfMe = this;
        super.setEnableVirtualButton(false);
        super.onCreate(savedInstanceState);
        // Workaround in https://stackoverflow.com/questions/16283079/re-launch-of-activity-on-home-button-but-only-the-first-time/16447508
        if (!isTaskRoot()) {
            // Android launched another instance of the root activity into an existing task
            //  so just quietly finish and go away, dropping the user back into the activity
            //  at the top of the stack (ie: the last state of this task)
            // Don't need to finish it again since it's finished in super.onCreate .
            return;
        }

        // Make sure we're running on Pie or higher to change cutout mode
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // Enable rendering into the cutout area
            WindowManager.LayoutParams lp = getWindow().getAttributes();
            //lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
            getWindow().setAttributes(lp);
        }
        // DO OTHER INITIALIZATION BELOW
        if(ActivityCompat.checkSelfPermission(AppActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION)
                != PackageManager.PERMISSION_GRANTED){//未开启定位权限
            NotifyCommon("需要开启定位权限");

            //开启定位权限,200是标识码
            ActivityCompat.requestPermissions(AppActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 200);
        }else{
            Toast.makeText(AppActivity.this,"已开启定位权限",Toast.LENGTH_LONG).show();
            NotifyCommon("已开启定位权限");
        }

        if(ActivityCompat.checkSelfPermission(AppActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED){//未开启定位权限
            NotifyCommon("需要开启精确定位权限");

            //开启定位权限,200是标识码
            ActivityCompat.requestPermissions(AppActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 200);
        }else{
            Toast.makeText(AppActivity.this,"已开启精确定位权限",Toast.LENGTH_LONG).show();
            NotifyCommon("已开启精确定位权限");
        }

        bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        // Use this check to determine whether BLE is supported on the device. Then
        // you can selectively disable BLE-related features.
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            Toast.makeText(this, "不支持", Toast.LENGTH_SHORT).show();
            NotifyCommon("不支持BLE");

        }
        bluetoothAdapter = bluetoothManager.getAdapter();

        // Ensures Bluetooth is available on the device and it is enabled. If not,
        // displays a dialog requesting user permission to enable Bluetooth.
        if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
            Toast.makeText(this, "打开蓝牙", Toast.LENGTH_SHORT).show();
            NotifyCommon("打开蓝牙");
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
        }

        boolean initSuccess = BlePenStreamManager.getInstance().init(getApplication(), HSDLicense.getBytes());
        if (!initSuccess) {
            Toast.makeText(this, "初始化失败，请到开放平台申请授权或检查设备是否支持蓝牙BLE", Toast.LENGTH_LONG).show();
        }
        BlePenStreamManager.getInstance().enableLog(true);
        //BlePenStreamManager.getInstance().clearMemoryCache();

        //handler = new Handler();
        //scanLeDevice(true);
        fromTongMengInfo();
        NotifyCommon("初始化完成...");
        BleCppInit();

        ZXYBSdk.XYInit(getApplication());
        bindB5Service();
    }


    //从童蒙得到信息
    private void fromTongMengInfo()
    {
        Intent tmIntent = getIntent();
        oneGCD = (GoodCopyData)tmIntent.getSerializableExtra("good_copy_data");
        if(oneGCD == null){
            isFromTongMeng = false;
            Log.e("GoodCopyData","GoodCopyData=null");
            return;
        }

        isFromTongMeng = true;
        Log.e("GoodCopyData","uid="+String.valueOf(oneGCD.getUid()));
        Log.e("GoodCopyData","name="+oneGCD.getName());
        Log.e("GoodCopyData","classId="+String.valueOf(oneGCD.getClass_id()));
        Log.e("GoodCopyData","unitId="+String.valueOf(oneGCD.getUnit_id()));
    }

    private Handler btB5handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            switch (msg.what) {
                case ZXYB_DATA:
                    Bundle bundle = msg.getData();
                    //板子原始坐标
                    int x = bundle.getInt("x");
                    int y = bundle.getInt("y");
                    //压力
                    float pressure = bundle.getFloat("pressure");
                    //根据屏幕转换坐标
                    int tx = bundle.getInt("tx");
                    int ty = bundle.getInt("ty");
                    int ps = bundle.getInt("penStatus");

/*
                    XYDataPacket xyDataPacket = new XYDataPacket();
                    xyDataPacket.x = x;
                    xyDataPacket.y = y;
                    xyDataPacket.penStatus = ps;
                    xyDataPacket.pressure = pressure;
 */
//                    ToastUtils.showLong("板子原始坐标 x == " + x + "   y == " +y);
                    //0 = hover / 1 down / 2 move / 3 up / 4 = leaving
                    //Log.e("btb5", "板子原始坐标 x == " + x + "   y == " +y+"    penStatus == "+ps+"    pressure="+pressure);
//                    EventBus.getDefault().post(xyDataPacket);
                    BtB5ReciveData(ps,x,y,pressure);
                    notifyWriting();

                    break;
                case ZXYB_KEY_INDEX:
                    // keyindex值范围：101(保存）-112(上页)
                    int keyIndex=msg.getData().getInt("keyIndex", 0);
//                    KeyIndex keyIndex = new KeyIndex();
//                    keyIndex.setKeyIndex(msg.getData().getInt("keyIndex", 0));
//                    EventBus.getDefault().post(keyIndex);
                    //ToastUtils.showLong("工具栏按键 ====   " + keyIndex);
                    Log.e("TAG", "工具栏按键 ====   " + keyIndex);
                    break;
                case ZXYB_BLE_STATUS:
                    //0连接 -1断开
                    int ble_status = msg.getData().getInt("ble_status", -1);
                    if(ble_status == 0){
                        isBtB5Connect = true;
                    }else{
                        isBtB5Connect = false;
                    }
                    String mac = msg.getData().getString("mac");
                    Log.e("mmacac", "mac:   " + mac);
                    //ToastUtils.showLong("慧板链接状态 ====   " + ble_status);
                    Log.e("TAG", "慧板链接状态 ====   " + ble_status);
                    break;

                case ZXYB_PEN_TYPE:
//                    penType 0 :画笔  1:鼠标  默认下是鼠标
                    btB5Type = msg.getData().getInt("penType", 0);
                    //ToastUtils.showLong("慧板模式 ====   " + penType);
                    Log.e("TAG", "慧板模式 ====   " + btB5Type);
                    if(btB5Type == 1){
                        Intent intent1=new Intent(ZXYB_MOUSE_STATUS_ACTION);
                        intent1.putExtra("penType",0); //0 画笔 1鼠标
                        sendBroadcast(intent1);
                    }
                    break;
            }
            return false;
        }
    });

    private void notifyWriting() {
        if(!isFromTongMeng ||
           oneGCD == null
        ){
            return;
        }

        if((System.currentTimeMillis() - lastTongMengTimestamp) < 10000){
            return;
        }

        Log.d("submitNotifyWrite",String.valueOf(System.currentTimeMillis())+"-"+String.valueOf(lastTongMengTimestamp)+"="+String.valueOf((System.currentTimeMillis() - lastTongMengTimestamp)));
        lastTongMengTimestamp = System.currentTimeMillis();
        writeReportThreadExecutor.execute(new Runnable() {
            public void run() {
                    String data = "{\n" +
                            "\"uid\": "+String.valueOf(oneGCD.getUid())+",\n" +
                            "\"name\": \""+oneGCD.getName()+"\",\n" +
                            "\"uclass_id\": "+oneGCD.getClass_id()+",\n" +
                            "\"note_status\": 1,\n" +
                            "\"write_status\":1\n" +
                            "}";
                    String retData = HttpUtils.submitJsonData("https://v3.xroom.net/v3/online/users/update",data);
                    Log.d("submitNotifyWrite:", retData);
            }
        });
    }

    private ServiceConnection btB5serverConnection = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
        }

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            btB5serverMessenger = new Messenger(iBinder);
            Message message = new Message();
            message.what = 1;
            message.replyTo = btB5clientMessenger;
            try {
                btB5serverMessenger.send(message);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    };

    private void bindB5Service() {
        btB5clientMessenger = new Messenger(btB5handler);
        try {
            final Intent intent = new Intent();
            // intent.setClassName("com.zxyb.main", "com.zxyb.main.service.SerialService");
            intent.setClassName("com.zxyb.sdk", "com.zxyb.sdk.MouseService");    // com.server.MySevice为Service的Action
            getContext().startService(intent);
            btB5handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    getContext().bindService(intent, btB5serverConnection, BIND_AUTO_CREATE);
                    getContext().sendBroadcast(new Intent().setAction(ZXYB_MOUSE_STATUS_ACTION).putExtra("showMouse", 0));

                    Intent intent1=new Intent(ZXYB_MOUSE_STATUS_ACTION);
                    intent1.putExtra("penType",0); //0 画笔 1鼠标
                    sendBroadcast(intent1);
                }
            }, 200);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        //myB5BU.unbind();
        bt5Unbind();
    }

    private void bt5Unbind()
    {
        getContext().sendBroadcast(new Intent().setAction(ZXYB_MOUSE_STATUS_ACTION).putExtra("showMouse", 1));
        getContext().unbindService(btB5serverConnection);
    }

    public void disconnectBle(){
        if(bluetoothGatt != null) {
            bluetoothGatt.discoverServices();
            bluetoothGatt.disconnect();
            bluetoothGatt.close();
        }

        if(connnectedDevice != null) {
            BlePenStreamManager.getInstance().disconnect(connnectedDevice);
        }
    }

    public void connectBLEByMacId(String macId){
        if(macId.equals("00-00-00-00-00-00")) {
            btB5handler.postDelayed(new Runnable(){
                public void run() {
                    BLEConnectSuccess(3);
                }
            }, 500);
        }else if(scanHSDBLEList.containsKey(macId)) {
            stopScanBle();

            if(scanHSDBLEList.get(macId).getName().indexOf("XJ") != -1) {
                connnectedDevice = scanHSDBLEList.get(macId);

                bluetoothGatt = scanHSDBLEList.get(macId).getDevice().connectGatt(AppActivity.this, true, mBluetoothGattCallback, TRANSPORT_LE);
            }else if(scanHSDBLEList.get(macId).getName().indexOf("TD-") != -1) {
                connnectedDevice = scanHSDBLEList.get(macId);
                connectBle();
            }
        }
    }

    private void stopScanBle(){
        mScanning = false;
        Log.d("bttt-java", "stopLeScan");
        bluetoothAdapter.stopLeScan(leScanCallback);
        BlePenStreamManager.getInstance().cancelScan();
        StopBluetoothScan();
    }
    // Device scan callback.
    public BluetoothAdapter.LeScanCallback leScanCallback =
            new BluetoothAdapter.LeScanCallback() {
                @Override
                public void onLeScan(final BluetoothDevice device, int rssi,
                                     byte[] scanRecord)
                {
                    if(device.getName() != null) {
                        if(device.getName().indexOf("XJ") != -1 ||
                           device.getName().indexOf("TD-") != -1
                        ) {
                            synchronized (scanBLEList) {
                                if (!scanBLEList.containsKey(device.getAddress())) {
                                    scanBLEList.put(device.getAddress(), device);
                                    Log.d("bttt-java", "onLeScan:" + device.getName() + ",addr" + device.getAddress()+",getDeviceClass="+String.valueOf(device.getBluetoothClass().getDeviceClass())+",marjorDevice="+String.valueOf(device.getBluetoothClass().getMajorDeviceClass())+",getBluetoothClass="+String.valueOf(device.getBluetoothClass()));
                                    ScanCallback(device.getName(), device.getAddress(), rssi,1);
                                }
                            }
                        }

                        if(isBtB5Connect){
                            synchronized (scanBLEList) {
                                if (!scanBLEList.containsKey("00-00-00-00-00-00")) {
                                    scanBLEList.put("00-00-00-00-00-00", device);
                                    Log.d("bttt-java", "蓝牙网关");
                                    ScanCallback("蓝牙网关", "00-00-00-00-00-00", 0,3);
                                }
                            }
                        }
                    }
                }
    };

    public void scanLeDevice(final boolean enable) {
        if (enable) {
             mScanning = true;

            scanBLEList.clear();
            //boolean isOk = bluetoothAdapter.startLeScan(leScanCallback);
            Log.d("bttt-java", "startLeScan");

            //======= 慧思得の比 ===========
            BlePenStreamManager.getInstance().scan(hsdScanCallback);
            scanHSDBLEList.clear();

            StartBluetoothScan();


            if(isBtB5Connect){
                synchronized (scanBLEList) {
                    if (!scanBLEList.containsKey("00-00-00-00-00-00")) {
                        scanBLEList.put("00-00-00-00-00-00", null);
                    }

                    Log.d("bttt-java", "蓝牙网关");
                    ScanCallback("蓝牙网关", "00-00-00-00-00-00", 0,3);
                }
            }
        } else {
            mScanning = false;
            bluetoothAdapter.stopLeScan(leScanCallback);
            Log.d("bttt-java", "stopLeScan");

            BlePenStreamManager.getInstance().cancelScan();

        }
    }

    BleScanCallback hsdScanCallback = new BleScanCallback() {
        @Override
        public void onScanStarted(boolean success) {
            Log.d("bttt-java", "hsd->onScanStarted: "+String.valueOf(success));
            if(!success){
                StopBluetoothScan();
            }
        }

        @Override
        public void onLeScan(BleDevice bleDevice) {
            Log.d("bttt-java", "hsd->onLeScan: "+bleDevice.getName()+bleDevice.getMac());

            synchronized (scanHSDBLEList) {
                if(bleDevice.getName().indexOf("XJ") != -1 ||
                        bleDevice.getName().indexOf("TD-") != -1
                ) {

                    if (!scanHSDBLEList.containsKey(bleDevice.getMac())) {
                        scanHSDBLEList.put(bleDevice.getMac(), bleDevice);

                        //.getBluetoothClass().getMajorDeviceClass()
                        Log.d("bttt-java", "hsd->onScanning:" + bleDevice.getName() + ",addr" + bleDevice.getMac() + ",getDeviceClass=" + bleDevice.getDevice().getBluetoothClass().getDeviceClass() + ",marjorDevice=" + bleDevice.getDevice().getBluetoothClass().getMajorDeviceClass() + ",type=" + bleDevice.getDevice().getType());


                        ScanCallback(bleDevice.getName(), bleDevice.getMac(), bleDevice.getRssi(), 1);
                    }
                }

                if(isBtB5Connect){
                    synchronized (scanBLEList) {
                        if (!scanBLEList.containsKey("00-00-00-00-00-00")) {
                            scanBLEList.put("00-00-00-00-00-00", bleDevice.getDevice());
                            Log.d("bttt-java", "蓝牙网关");
                            ScanCallback("蓝牙网关", "00-00-00-00-00-00", 0,3);
                        }
                    }
                }
            }

            super.onLeScan(bleDevice);
        }

        @Override
        public void onScanning(BleDevice bleDevice) {
            Log.d("bttt-java", "hsd->onScanning: "+bleDevice.getName()+bleDevice.getMac());
        }

        @Override
        public void onScanFinished(List<BleDevice> scanResultList) {
            Log.d("bttt-java", "hsd->onScanFinished: "+String.valueOf(scanResultList.size()));
            //StopBluetoothScan();
            if(mScanning) {
                BlePenStreamManager.getInstance().scan(hsdScanCallback);
            }
        }
    };

    @Override
    public void onRequestPermissionsResult(int requestCode,  String[] permissions,  int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode){
            case 200://刚才的识别码
                if(grantResults[0] == PackageManager.PERMISSION_GRANTED){//用户同意权限,执行我们的操作

                }else{//用户拒绝之后,当然我们也可以弹出一个窗口,直接跳转到系统设置页面
                    Toast.makeText(AppActivity.this,"未开启定位权限,请手动到设置去开启权限",Toast.LENGTH_LONG).show();
                }
                break;
            default:break;
        }
    }
}
